package com.atguigu.test.config;

import com.atguigu.test.boot.annotation.MyConditionalOnMissBean;
import com.atguigu.test.boot.annotation.MybatisParameterVerify;
import com.atguigu.test.boot.properties.MySqlProperties;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;

import javax.sql.DataSource;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author zp
 * @version 1.0
 * @description: mybatis自动导入配置类类
 * @date 2023/2/8 19:11
 */
@Configuration(proxyBeanMethods = false)
@MybatisParameterVerify
public class MyBatisAutoConfig {
    public static final String MY_BATIS_NAME = "mybatis";
    @Bean(initMethod = "init")
    @MyConditionalOnMissBean(className = MySqlProperties.class)
    public MySqlProperties mySqlProperties(){
        MySqlProperties mySqlProperties = new MySqlProperties();
        return mySqlProperties;
    }

    @MyConditionalOnMissBean(className = DataSource.class)
    @Bean
    public DataSource dataSource(MySqlProperties mySqlProperties) throws SQLException {
        return new SimpleDriverDataSource(DriverManager.getDriver(mySqlProperties.getUrl())
                ,mySqlProperties.getUrl()
                ,mySqlProperties.getUsername()
                ,mySqlProperties.getPassword());
    }

    @MyConditionalOnMissBean(className = SqlSessionFactoryBuilder.class)
    @Bean
    public SqlSessionFactoryBuilder sqlSessionFactoryBuilder(){
        return new SqlSessionFactoryBuilder();
    }

    @MyConditionalOnMissBean(className = TransactionFactory.class)
    @Bean
    public TransactionFactory transactionFactory(){
        return new JdbcTransactionFactory();
    }

    @MyConditionalOnMissBean(className = Environment.class)
    @Bean
    public Environment environment(TransactionFactory transactionFactory, DataSource dataSource,MySqlProperties mySqlProperties){
        return new Environment(MY_BATIS_NAME,transactionFactory,dataSource);
    }

    @MyConditionalOnMissBean(className = org.apache.ibatis.session.Configuration.class)
    @Bean
    public org.apache.ibatis.session.Configuration configuration(Environment environment,MySqlProperties mySqlProperties){
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setEnvironment(environment);
        configuration.getTypeAliasRegistry().registerAliases(mySqlProperties.getRegisterAliasesPackageUrl());
        configuration.addMappers(mySqlProperties.getAddMappersPackageUrl());
        return configuration;
    }

    @MyConditionalOnMissBean(className = SqlSessionFactory.class)
    @Bean
    public SqlSessionFactory sqlSessionFactory(org.apache.ibatis.session.Configuration configuration){
        return new SqlSessionFactoryBuilder().build(configuration);
    }

    @MyConditionalOnMissBean(className = SqlSession.class)
    @Bean
    public SqlSession sqlSession(SqlSessionFactory sqlSessionFactory){
        return sqlSessionFactory.openSession();
    }

}
